module objects.objectinstance;

import material.material;
import objects.abstractobject;
import objects.triangle;
import utils.matrix;
import utils.vector2;
import utils.vector3;

///acts as a proxy between the actual object class and the scene,
///handling translation, rotation and scaling of triangles and
///normals
class ObjectInstance : AbstractObject {
    private {
        AbstractObject mObject;
        Matrix3f mMatrixRot, mMatrixRotScale;
        Vector3f mTranslate;
    }

    this(AbstractObject obj, float scale, Vector3f rot, Vector3f trans) {
        mObject = obj;
        mMatrixRot = Matrix3f.fromAngles(rot);
        mMatrixRotScale = mMatrixRot * scale;
        mTranslate = trans;
    }

    public Triangle[] getTriangles() {
        Triangle[] tris = mObject.getTriangles().dup;
        //rotate/translate/scale by factors set before
        //xxx use quaternion matrix
        foreach (inout Triangle tri; tris) {
            tri.v[0] = (mMatrixRotScale * tri.v[0]) + mTranslate;
            tri.v[1] = (mMatrixRotScale * tri.v[1]) + mTranslate;
            tri.v[2] = (mMatrixRotScale * tri.v[2]) + mTranslate;
        }
        return tris;
    }

    public TriangleNorms getTriNormals(int triIdx, bool interpolate) {
        TriangleNorms norms = mObject.getTriNormals(triIdx, interpolate);
        norms.n[0] = mMatrixRot * norms.n[0];
        norms.n[1] = mMatrixRot * norms.n[1];
        norms.n[2] = mMatrixRot * norms.n[2];
        return norms;
    }

    public Vector2f[] getTexCoords(int triIdx) {
        return mObject.getTexCoords(triIdx);
    }

    public Material getTriMaterial(int triIdx) {
        return mObject.getTriMaterial(triIdx);
    }

    public void setMaterial(Material mat, int idx = 0) {
        mObject.setMaterial(mat, idx);
    }

    public Material getMaterial(int idx = 0) {
        return mObject.getMaterial(idx);
    }
}
